package com.huike.clues.service.impl;

import com.huike.clues.mapper.SysDeptMapper;
import com.huike.clues.mapper.SysRoleMapper;
import com.huike.clues.mapper.SysUserMapper;
import com.huike.clues.service.ISysDeptService;
import com.huike.common.core.domain.TreeSelect;
import com.huike.common.core.domain.entity.SysDept;
import com.huike.common.core.domain.entity.SysRole;
import com.huike.common.exception.BaseException;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * @author EthanRuins
 * @apiNote 部门表(SysDept)表服务实现类
 * @since 2023-07-11 15:17:49
 */
@Service("sysDeptService")
@AllArgsConstructor
public class SysDeptServiceImpl implements ISysDeptService {
    private final SysDeptMapper sysDeptMapper;
    private final SysUserMapper sysUserMapper;
    private final SysRoleMapper sysRoleMapper;

    /**
     * 校验部门名称是否唯一
     *
     * @param deptName 部门名称
     * @return true-唯一 false-不唯一
     */
    @Override
    public boolean checkNameUnique(String deptName) {
        SysDept deptDb = sysDeptMapper.getByName(deptName);
        return deptDb != null;
    }

    /**
     * 添加部门
     *
     * @param sysDept 新部门数据
     */
    @Override
    public int add(SysDept sysDept) {
        // TODO 缓存
        SysDept parentDept = getById(sysDept.getParentId());
        sysDept.setAncestors(parentDept.getAncestors() + "," + sysDept.getParentId());
        return sysDeptMapper.save(sysDept);
    }

    /**
     * 更新部门数据
     *
     * @param sysDept 新部门数据
     */
    @Override
    public int update(SysDept sysDept) {
        // TODO 缓存
        SysDept parentDept = getById(sysDept.getParentId());
        sysDept.setAncestors(parentDept.getAncestors() + "," + sysDept.getParentId());
        return sysDeptMapper.update(sysDept);
    }

    /**
     * 根据ID删除部门信息
     *
     * @param deptId 部门id
     * @return 影响行数
     */
    @Override
    public int delete(Long deptId) {
        // TODO 缓存
        SysDept dept = sysDeptMapper.getById(deptId);
        if (dept == null) {
            throw new BaseException("部门不存在");
        }
        List<SysDept> deptByParentId = sysDeptMapper.getByParentId(deptId);
        if (deptByParentId != null && deptByParentId.size() != 0) {
            throw new BaseException("部门存在子部门，不允许删除");
        }
        List<Long> userListByDeptIds = sysUserMapper.selectUserListByDeptIds(new Long[]{deptId});
        if (userListByDeptIds != null && userListByDeptIds.size() != 0) {
            throw new BaseException("部门存在用户，不允许删除");
        }
        return sysDeptMapper.deleteById(deptId);
    }

    /**
     * 根据ID获取部门信息
     * @param deptId 部门ID
     * @return 部门信息
     */
    @Override
    public SysDept getById(Long deptId) {
        return sysDeptMapper.getById(deptId);
    }

    /**
     * 根据指定条件查询部门列表
     *
     * @param dept 查询条件
     * @return 部门列表
     */
    @Override
    public List<SysDept> getDeptList(SysDept dept) {
        return sysDeptMapper.getDeptList(dept);
    }

    /**
     * 查询部门列表（排除指定部门结点）
     *
     * @param deptId 指定部门结点的ID
     * @return 部门列表
     */
    @Override
    public List<SysDept> excludeList(Long deptId) {
        List<SysDept> deptList = sysDeptMapper.getDeptList(new SysDept());
        deptList.removeIf(dept -> Objects.equals(deptId, dept.getDeptId()) ||
                dept.getAncestors().contains(deptId.toString()));
        return deptList;
    }

    /**
     * 获取部门下拉树列表
     *
     * @return 下拉树列表
     */
    @Override
    public TreeSelect treeSelect() {
        List<SysDept> depts = getDeptList(new SysDept());
        return toTreeSelect(depts);
    }

    /**
     * 获取对应角色部门列表树
     *
     * @param roleId 对应角色ID
     * @return 列表树
     */
    @Override
    public List<TreeSelect> getRoleDeptTreeselect(Long roleId) {
        SysRole sysRole = sysRoleMapper.selectRoleByRoleId(roleId);
        return sysDeptMapper.getDeptListByRoleId(roleId, sysRole.isDeptCheckStrictly());
    }

    private TreeSelect toTreeSelect(List<SysDept> depts) {
        for (SysDept dept : depts) {
            Long deptId = dept.getDeptId();
            for (SysDept child : depts) {
                if (Objects.equals(deptId, child.getParentId())) {
                    dept.getChildren().add(child);
                }
            }
        }
        for (SysDept dept : depts) {
            if (Objects.equals(dept.getParentId(), 0L)) {
                return new TreeSelect(dept);
            }
        }
        return null;
    }
}
